package com.gpipe.dbwriter;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.gpipe.dirwatcherRealtime.DirectorySnapshotRealtime;
import com.gpipe.properties.InputProperties;
import com.gpipe.tools.GpipeInit;
import com.gpipe.tools.SignalList;


public class SendResultData extends AbstractSendResultData {

    protected boolean batchExecuted;

    /**
     * @param result            the data to insert
     * @param insertQuery       insert sql
     * @param cols              the num of columns to insert
     * @param insertTruncate    the sql of truncate
     * @param name              the name of this thread
     * @param amplificationFlag the flag whether or not to amplify the num
     */
    public void writeMysql(Map result, String insertQuery, int cols, String insertTruncate, String name, boolean amplificationFlag) {
        Connection connection = createConnect();

        try {
            Statement stmt = connection.createStatement();
            stmt.executeUpdate(insertTruncate);
            if (stmt != null) stmt.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        super.writeMysql(result, connection, insertQuery, cols, name, amplificationFlag);
    }

    /**
     * @param result            the data to insert
     * @param insertQuery       insert sql
     * @param cols              the num of columns to insert
     * @param name              the name of this thread
     * @param amplificationFlag the flag whether or not to amplify the num
     */
    public void writeMysql(Map result, String insertQuery, int cols, String name, boolean amplificationFlag) {
        Connection connection = createConnect();
        super.writeMysql(result, connection, insertQuery, cols, name, amplificationFlag);
    }


    public void writeMysql(String filePath, Connection connection) {
        PreparedStatement prepStatement = null;
        if (connection == null) {
            connection = createConnect();
        }
        if (connection == null) {
            GpipeInit.writeLogs("can not connect to mysql, please check status of mysql service.");
            System.exit(0);
        }
        StringBuilder insertQuery = new StringBuilder("INSERT INTO signal_data_gz(MSG_TYPE,MSG_SUB_TYPE,ACC_NBR,LAC,CI,START_TIME)VALUES(?,?,?,?,?,?)");
        try {
            prepStatement = connection.prepareStatement(insertQuery.toString());
        } catch (SQLException e) {
            e.printStackTrace();
        }

        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                if (line != null) {
                    String[] fields = null;
                    fields = line.split("\\|", -1);
                    //2,3,5,9,10,11
                    if (fields.length >= 11) {
                        try {
                            if (GpipeInit.isNotEmpty(fields[5])) {
                                prepStatement.setString(1, fields[2]);
                                prepStatement.setString(2, fields[3]);
                                prepStatement.setString(3, fields[5]);
                                prepStatement.setString(4, fields[9]);
                                prepStatement.setString(5, fields[10]);
                                prepStatement.setString(6, fields[11]);
                                prepStatement.addBatch();
                                counter.incrementAndGet();
                                if (counter.get() == batchSize) {
                                    executeBatch(prepStatement);
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (counter.get() > 0) {
            try {
                executeBatch(prepStatement);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        try {
            if (!connection.isClosed()) {
                connection.close();
            }
            prepStatement.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * @param resultMap         the data to write
     * @param name              the thread's name
     * @param fileName          the result file's name
     * @param amplificationFlag the flag whether or not to amplify the num
     */
    public void writeLocFTP(Map<String, Integer> resultMap, String name, String fileName, boolean amplificationFlag) {
        String filePath = DirectorySnapshotRealtime.homePath + File.separator + "signal_result_data" + File.separator + name + File.separator + fileName;
        String localPath = DirectorySnapshotRealtime.homePath + File.separator + "signal_result_data" + File.separator + name;
        String rcmPath = File.separator + "signal_result_data" + File.separator + name;
        writeLoc(filePath, resultMap, name, amplificationFlag);

        String shellPath = DirectorySnapshotRealtime.homePath + File.separator + "bin" + File.separator + DirectorySnapshotRealtime.ftpShell;
        System.out.println("--##--shellPath:" + shellPath);

        ftp(shellPath, fileName, localPath, rcmPath, InputProperties.inputdataConf.get("ftpHost"), InputProperties.inputdataConf.get("ftpUser"), InputProperties.inputdataConf.get("ftpPassword"));
    }

    private void ftp(String shellPath, String fileName, String localPath, String rcmPath, String ftpHost, String ftpUser, String ftpPassword) {
        try {
            Process ps;
            String cmd = shellPath + " " + fileName + " " + localPath + " " + rcmPath + " " + ftpHost + " " + ftpUser + " " + ftpPassword;
            System.out.println("--##--ftp cmd:" + cmd);
            ps = Runtime.getRuntime().exec(cmd);
            ps.waitFor();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void runShellLoc(){

    }

    public int runShell(String shellPath, String[] paras) {
        try {
            Process ps;
            String cmd = shellPath;
            for (String para : paras) {
                cmd = cmd + " " + para;
            }
            System.out.println("--##--shell cmd:" + cmd);
            ps = Runtime.getRuntime().exec(cmd);
            return ps.waitFor();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return -1;
    }

    public void writeLoc(String filePath, Map resultMap) {
        FileOutputStream outSTr = null;
        BufferedOutputStream Buff = null;
        String line = null;

        try {
            outSTr = new FileOutputStream(new File(filePath));
            Buff = new BufferedOutputStream(outSTr);

            Iterator iter = resultMap.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                Object key = entry.getKey();
                Object value = entry.getValue();
                line = key.toString() + "|" + value.toString();

                Buff.write(line.getBytes());
                Buff.write("\n".getBytes());//linux newline
            }
            Buff.flush();
            Buff.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void writeLoc(String filePath, Map<String, Integer> resultMap, String name, boolean amplificationFlag) {
        FileOutputStream outSTr = null;
        BufferedOutputStream Buff = null;
        String line = null;
        try {
            String dirPath = filePath.substring(0, filePath.lastIndexOf(File.separator));
            File fDirPath = new File(dirPath);
            if (!fDirPath.exists()) {
                fDirPath.mkdirs();
            }


            outSTr = new FileOutputStream(new File(filePath));

            Buff = new BufferedOutputStream(outSTr);
            Iterator iter = resultMap.entrySet().iterator();
            String startTime = GpipeInit.writeLogs("--##--write '" + name + "' data begin!");
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                Object key = entry.getKey();
                Object value = entry.getValue();
                if (amplificationFlag) {
                    line = key + "|" + GpipeInit.proportionRound(value.toString());
                } else {
                    line = key + "|" + value;
                }

                Buff.write(line.getBytes());
                Buff.write("\n".getBytes());//linux newline
            }

            String endTime = GpipeInit.writeLogs("--##--write '" + name + "' data end!");

            System.out.println("----write '" + name + "' data duration=" + GpipeInit.duration(startTime, endTime, "yyyy-MM-dd HH:mm:ss") + "s");
            Buff.flush();
            Buff.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }


    public static void main(String[] args) throws SQLException {
        SendResultData ss = new SendResultData();

        String[] paras = new String[]{"1","2","3","4","5"};

        ss.runShell("/home/test/test.sh",paras);

    }


}
